package com.ruoyi.web.controller.common;

import com.codahale.metrics.*;
import java.util.Map;

public class AllMetricsFetcher {

    private final MetricRegistry metricRegistry;

    public AllMetricsFetcher(MetricRegistry metricRegistry) {
        this.metricRegistry = metricRegistry;
    }

    public String exportMetricsToPrometheusFormat() {
        StringBuilder sb = new StringBuilder();

        // 处理 Gauges
        Map<String, Gauge> gauges = metricRegistry.getGauges();
        for (Map.Entry<String, Gauge> entry : gauges.entrySet()) {
            String name = sanitizeMetricName(entry.getKey());
            Gauge gauge = entry.getValue();
            Object value = gauge.getValue();
            if (value instanceof Number) {
                sb.append("# HELP ").append(name).append(" Gauge metric from Dropwizard<br/>");
                sb.append("# TYPE ").append(name).append(" gauge<br/>");
                sb.append(name).append(" ").append(value).append("<br/>");
            }
        }

        // 处理 Counters
        Map<String, Counter> counters = metricRegistry.getCounters();
        for (Map.Entry<String, Counter> entry : counters.entrySet()) {
            String name = sanitizeMetricName(entry.getKey());
            Counter counter = entry.getValue();
            sb.append("# HELP ").append(name).append(" Counter metric from Dropwizard<br/>");
            sb.append("# TYPE ").append(name).append(" counter<br/>");
            sb.append(name).append(" ").append(counter.getCount()).append("<br/>");
        }

        // 处理 Histograms
        Map<String, Histogram> histograms = metricRegistry.getHistograms();
        for (Map.Entry<String, Histogram> entry : histograms.entrySet()) {
            String baseName = sanitizeMetricName(entry.getKey());
            Histogram histogram = entry.getValue();
            Snapshot snapshot = histogram.getSnapshot();

            sb.append("# HELP ").append(baseName).append("_count Histogram count metric from Dropwizard<br/>");
            sb.append("# TYPE ").append(baseName).append("_count counter<br/>");
            sb.append(baseName).append("_count ").append(histogram.getCount()).append("<br/>");

            sb.append("# HELP ").append(baseName).append("_sum Histogram sum metric from Dropwizard<br/>");
            sb.append("# TYPE ").append(baseName).append("_sum gauge<br/>");
            sb.append(baseName).append("_sum ").append(snapshot.getMean() * histogram.getCount()).append("<br/>");

            double[] quantiles = {0.5, 0.75, 0.95, 0.99};
            for (double quantile : quantiles) {
                String quantileName = baseName + "_" + (int) (quantile * 100);
                sb.append("# HELP ").append(quantileName).append(" Histogram quantile metric from Dropwizard<br/>");
                sb.append("# TYPE ").append(quantileName).append(" gauge<br/>");
                sb.append(quantileName).append(" ").append(snapshot.getValue(quantile)).append("<br/>");
            }
        }

        // 处理 Meters
        Map<String, Meter> meters = metricRegistry.getMeters();
        for (Map.Entry<String, Meter> entry : meters.entrySet()) {
            String baseName = sanitizeMetricName(entry.getKey());
            Meter meter = entry.getValue();

            sb.append("# HELP ").append(baseName).append("_count Meter count metric from Dropwizard<br/>");
            sb.append("# TYPE ").append(baseName).append("_count counter<br/>");
            sb.append(baseName).append("_count ").append(meter.getCount()).append("<br/>");

            sb.append("# HELP ").append(baseName).append("_one_minute_rate Meter one minute rate metric from Dropwizard<br/>");
            sb.append("# TYPE ").append(baseName).append("_one_minute_rate gauge<br/>");
            sb.append(baseName).append("_one_minute_rate ").append(meter.getOneMinuteRate()).append("<br/>");

            sb.append("# HELP ").append(baseName).append("_five_minute_rate Meter five minute rate metric from Dropwizard<br/>");
            sb.append("# TYPE ").append(baseName).append("_five_minute_rate gauge<br/>");
            sb.append(baseName).append("_five_minute_rate ").append(meter.getFiveMinuteRate()).append("<br/>");

            sb.append("# HELP ").append(baseName).append("_fifteen_minute_rate Meter fifteen minute rate metric from Dropwizard<br/>");
            sb.append("# TYPE ").append(baseName).append("_fifteen_minute_rate gauge<br/>");
            sb.append(baseName).append("_fifteen_minute_rate ").append(meter.getFifteenMinuteRate()).append("<br/>");
        }

        // 处理 Timers
        Map<String, Timer> timers = metricRegistry.getTimers();
        for (Map.Entry<String, Timer> entry : timers.entrySet()) {
            String baseName = sanitizeMetricName(entry.getKey());
            Timer timer = entry.getValue();
            Snapshot snapshot = timer.getSnapshot();

            sb.append("# HELP ").append(baseName).append("_count Timer count metric from Dropwizard<br/>");
            sb.append("# TYPE ").append(baseName).append("_count counter<br/>");
            sb.append(baseName).append("_count ").append(timer.getCount()).append("<br/>");

            sb.append("# HELP ").append(baseName).append("_sum Timer sum metric from Dropwizard<br/>");
            sb.append("# TYPE ").append(baseName).append("_sum gauge<br/>");
            sb.append(baseName).append("_sum ").append(snapshot.getMean() * timer.getCount()).append("<br/>");

            double[] quantiles = {0.5, 0.75, 0.95, 0.99};
            for (double quantile : quantiles) {
                String quantileName = baseName + "_" + (int) (quantile * 100);
                sb.append("# HELP ").append(quantileName).append(" Timer quantile metric from Dropwizard<br/>");
                sb.append("# TYPE ").append(quantileName).append(" gauge<br/>");
                sb.append(quantileName).append(" ").append(snapshot.getValue(quantile)).append("<br/>");
            }
        }

        return sb.toString();
    }

    private String sanitizeMetricName(String name) {
        return name.replaceAll("[^a-zA-Z0-9_]", "_");
    }
}
